########### Algorithmic representation: Study 3 online survey experiment ######
# Code for the replication of the analyses reported in the paper:
# Finding the white male: The prevalence and consequences of 
#algorithmic gender and race bias in political Google searches

# doi: XXXXXXXXXXXXXX

# Contact corresponding author for help/information with code problems


#  OVERVIEW OF CODE SECTIONS----------------------------------------------------

# 0: Data preparation
# H3: Tests of baseline bias hypothesis
# H4: Tests of distribution bias hypothesis


#if using r studio, display content outline with Ctrl + Shift + O



# 0 - Data preparation ----------------------
#libraries
library(tidyverse) # for tidy data manipulations
library(lme4) # For multilevel models
library(lmerTest) # for multilevel models
library(marginaleffects) # extracting results from multilevel models
library(sjPlot) # exporting regression results
library(sjmisc) #exporting regresion resuls
library(mediation) # for mediation analysis (H4)
library(viridis)
library(gghighlight)
library(Hmisc)
library(lemon)

#get local path to the folder containing the data files (within the folder where replication files are stored)
path_to_folder <- "" 
setwd(path_to_folder) #set working directory to that folder



#read_data and define data types
data <- read.csv("data/vpn_data_study4.csv", sep = ";",
                 na.strings = c("", "NA", "N/A")) %>%
  dplyr::select(-gender_4_TEXT) %>% # drop this variable, as it causes problem later on and we do not use it
  # (re-)define data types
  mutate_if(is.character,
            ~ ifelse(grepl("^-?\\d+(\\.\\d+)?$", .), as.numeric(.), .))%>%
  #rename some of the variables consistent with previous study
  rename(age = age_1,
        se_use = Q41_1,
        viability_female = viability_2,
        viability_nonwhite = viability_3,
        viability_femaleNonwhite = viability_4,
        viability_republican = viability_5,
        ideology_1 = ideology_1_1,
        ideology_2 = ideology_2_1,
        chance_high_wagner = Q49_0_GROUP_1,
        chance_high_hoffman = Q49_0_GROUP_2,
        chance_high_schmidt = Q49_0_GROUP_3,
        chance_high_meyer = Q49_0_GROUP_4,
        chance_high_ramirez = Q49_0_GROUP_5,
        chance_high_wood = Q49_0_GROUP_6,
        chance_high_yang = Q49_0_GROUP_12,
        chance_high_jackson = Q49_0_GROUP_13,
        chance_average_wagner = Q49_1_GROUP_1,
        chance_average_hoffman = Q49_1_GROUP_2,
        chance_average_schmidt = Q49_1_GROUP_3,
        chance_average_meyer = Q49_1_GROUP_4,
        chance_average_ramirez = Q49_1_GROUP_5,
        chance_average_wood = Q49_1_GROUP_6,
        chance_average_yang = Q49_1_GROUP_12,
        chance_average_jackson = Q49_1_GROUP_13,
        chance_small_wagner = Q49_2_GROUP_1,
        chance_small_hoffman = Q49_2_GROUP_2,
        chance_small_schmidt = Q49_2_GROUP_3,
        chance_small_meyer = Q49_2_GROUP_4,
        chance_small_ramirez = Q49_2_GROUP_5,
        chance_small_wood = Q49_2_GROUP_6,
        chance_small_yang = Q49_2_GROUP_12,
        chance_small_jackson = Q49_2_GROUP_13,
        representation_female = post_representation_2,
        representation_military = post_representation_6,
        representation_business = post_representation_10,
        representation_law = post_representation_7,
        representation_nonwhite = post_representation_8,
        representation_femaleNonwhite = post_representation_9) %>%
  #set values in the specific electablitliy ("chance_) variables to zero if a name wasn't picked
  mutate_at(vars(starts_with("chance_")), ~ifelse(is.na(.), 0, .)) %>%
  #recod specific electability vars
  # from -1 (small chances), 0 (average) to 1 (high chances)
  mutate(
    chance_wagner = case_when(
      chance_high_wagner == 1 ~ 1,
      chance_average_wagner == 1 ~ 0,
      chance_small_wagner == 1 ~ -1),
    chance_hoffman = case_when(
      chance_high_hoffman == 1 ~ 1,
      chance_average_hoffman == 1 ~ 0,
      chance_small_hoffman == 1 ~ -1),
    chance_schmidt = case_when(
      chance_high_schmidt == 1 ~ 1,
      chance_average_schmidt == 1 ~ 0,
      chance_small_schmidt == 1 ~ -1),
    chance_meyer = case_when(
      chance_high_meyer == 1 ~ 1,
      chance_average_meyer == 1 ~ 0,
      chance_small_meyer == 1 ~ -1),
    chance_ramirez = case_when(
      chance_high_ramirez == 1 ~ 1,
      chance_average_ramirez == 1 ~ 0,
      chance_small_ramirez == 1 ~ -1),
    chance_wood = case_when(
      chance_high_wood == 1 ~ 1,
      chance_average_wood == 1 ~ 0,
      chance_small_wood == 1 ~ -1),
    chance_yang = case_when(
      chance_high_yang == 1 ~ 1,
      chance_average_yang == 1 ~ 0,
      chance_small_yang == 1 ~ -1),
    chance_jackson = case_when(
      chance_high_jackson == 1 ~ 1,
      chance_average_jackson == 1 ~ 0,
      chance_small_jackson == 1 ~ -1),
    condition = factor(case_when(
      FL_18_DO_treatment_no_bias == 1 ~ "No bias",
      FL_18_DO_treatment_gender_bias == 1 ~ "Gender bias",
      FL_18_DO_treatment_race_bias == 1 ~ "Race bias",
      FL_18_DO_treatment_double_bias == 1 ~ "Double bias")),
         party_vote = factor(party_vote, 1:3, c("conservative","liberal","other")),
         gender = factor(gender, 1:4, c("male","female","other","other")))


#create selectors
efficacy_vars <- c("post_efficacy1", "post_efficacy2")
ideology_vars <- c("ideology_1", "ideology_2")

#create scales
data <- data%>%
  mutate(
    ideology = rowMeans(across(all_of(ideology_vars)), na.rm = TRUE),
    efficacy = rowMeans(across(all_of(efficacy_vars)), na.rm = TRUE),
    #create specific electability per group by averaging names together
    chance_whiteMale = (chance_wagner + chance_hoffman) / 2,
    chance_whiteFemale = (chance_meyer + chance_schmidt)/2,
    chance_nonwhiteMale = (chance_ramirez + chance_wood)/2,
    chance_nonwhiteFemale = (chance_yang + chance_jackson)/2,
    chance_nonwhite = (chance_yang + chance_jackson + chance_wood + chance_ramirez) /4,
    chance_female = (chance_meyer + chance_schmidt + chance_yang + chance_jackson) /4,
    condition = fct_relevel(condition,
                            "No bias","Gender bias","Race bias",
                            "Double bias"),
    #next to a factor with all conditiosn ("conditions"),
    # we also create dummies for each type of bias; we will use these in the mediation analyses
    gender_bias = case_when(
      condition %in% c("Gender bias","Double bias") ~ "bias",
      condition %in% c("Race bias", "No bias") ~ "balanced"),
    race_bias = case_when(
      condition %in% c("Race bias","Double bias") ~ "bias",
      condition %in% c("Gender bias", "No bias") ~ "balanced"),
    intersectional_bias = case_when(
      condition %in% c("Race bias","Double bias","Gender bias") ~ "bias",
      condition %in% c("No bias") ~ "balanced"))



# H3: Perceptual Bias ------------------------------------------------
# We test the perceptual bias hypothesis by running OLS models
#for the estimated representation of each group.
# The hypothesis test focuses on the main effect of condition


## estimated representation women politicians
m_rep_female  <- lm(representation_female ~ condition + gender +
                     party_vote + ideology + age + se_use,
                   data = data)

## estimated non-white politicians
m_rep_nonwhite  <- lm(representation_nonwhite ~ condition + gender +
                      party_vote + ideology + age +se_use,
                    data = data)

## estimated non-white women politicians
m_rep_nonwhiteFemale  <- lm(representation_femaleNonwhite ~ condition + gender +
                      party_vote + ideology + age + se_use,
                    data = data)

## export regression outputs; This is Table C4.1 in the Appendix
tab_model(m_rep_female,m_rep_nonwhite, m_rep_nonwhiteFemale,
          file = "outputs/Study4_TableC4.1_MainModelsH3.doc")




# Visualization: Figure 5 ----------------------------

#This segment reproduces Figure 5 in the main manuscript

# Create data for lines
rep_data <- data %>%
  pivot_longer(cols = starts_with("representation_"),
               names_to = "outcome",
               values_to = "representation",
               names_prefix = "representation_") %>%
  filter(outcome %in% c("female","nonwhite","femaleNonwhite"))%>%
  mutate(
    outcome = fct_relevel(outcome,
                          "female","nonwhite","femaleNonwhite"),
    outcome = fct_recode(outcome,
                         "% women" = "female", 
                         "% non-white"="nonwhite",
                         "% non-white women" = "femaleNonwhite"))

data_hline <- data.frame(outcome = unique(rep_data$outcome),
                         hline = c(29.0, 26.0, 13.3),
                         x = c(1,1,1))
Figure5 <- rep_data %>%
  ggplot(
    aes(x = condition, y = representation, group = condition, fill = condition)) +
  stat_summary(geom = "bar", fun.y = "mean", alpha = .8,
               width = .78, position = position_dodge(.8)) +
  stat_summary(geom = "errorbar", fun.data = "mean_se", width = .1, position = position_dodge(.8)) +
  scale_fill_manual(values=c("lightgrey","#3b528b","#35b779","#440154"))+
  facet_wrap(~ outcome, nrow = 1) +
  geom_hline(data = data_hline,
             aes(yintercept = hline), linetype = "dashed")+
  theme_classic() +
  coord_flex_cart(left = capped_vertical("both")) +
  labs(y = "Estimated descriptive representation in US House", x = "",
       title = "", fill = "")+
  scale_y_continuous(labels = scales::percent_format(
    accuracy = 1L, scale = 1),
    breaks = seq(0,35,5)) +
  theme(
    axis.text.x = element_text(angle = 45, hjust = 1),
    legend.position = "bottom",
    strip.text.x = element_text(
      size = 12, face = "bold"),
    strip.background = element_blank())+
  # theme(panel.spacing = unit(2, "lines")) +
  guides(fill = "none")


ggsave(Figure5, filename = "outputs/Study4_Figure5.jpeg", dpi = 800,
       width = 8, height = 4.5)




# H4: Strategic Bias ---------------------------------------------------------------
# We test our last hypotheses by running separate mediation models    
# for general/specific electability (H4a) and external efficacy (H4b)


# Note that viability is the name for the general electability measure;
# "chance" is the name for specific electability measure

# we run separate models for each group (i.e., women, non-white politicains, non-white politicians)
# and use the corresponding condition as a treatment

set.seed(666) # set seed for reproducible bootstrapping


## general electability ----------------------
med.fit_ElecFem <- lm(representation_female ~ gender_bias + age  + gender + ideology + party_vote +se_use,
              data = data )
out.fit_ElecFem <- lm(viability_female ~ gender_bias + age  + gender + ideology + representation_female +party_vote + se_use,
              data =  data)

main_med.out_ElecFem <- mediate(med.fit_ElecFem, out.fit_ElecFem, treat = "gender_bias", mediator = "representation_female",
                   sims = 10000, boot = TRUE, 
                   boot.ci.type = "bca")

# nonwhite
med.fit_ElecNonWhite <- lm(representation_nonwhite ~ race_bias + age  + gender + ideology + party_vote +se_use,
              data = data )
out.fit_ElecNonWhite <- lm(viability_nonwhite ~ race_bias + age  + gender + ideology + representation_nonwhite +party_vote + se_use,
              data =  data)

main_med.out_ElecNonWhite <- mediate(med.fit_ElecNonWhite, out.fit_ElecNonWhite, treat = "race_bias", mediator = "representation_nonwhite",
                   sims = 10000, boot = TRUE, 
                   boot.ci.type = "bca")

#intersectonal bias
med.fit_ElecInter <- lm(representation_femaleNonwhite ~ intersectional_bias + age  + gender + ideology + party_vote +se_use,
              data = data )
out.fit_ElecInter <- lm(viability_femaleNonwhite ~ intersectional_bias + age  + gender + ideology + representation_femaleNonwhite +party_vote + se_use,
              data =  data)

main_med.out_ElecInter <- mediate(med.fit_ElecInter, out.fit_ElecInter, treat = "intersectional_bias", mediator = "representation_femaleNonwhite",
                   sims = 10000, boot = TRUE, 
                   boot.ci.type = "bca")


## external efficacy --------------------------
med.fit_EffFem <- lm(representation_female ~ gender_bias + age  + gender + ideology + party_vote +se_use,
              data = data )
out.fit_EffFem <- lm(efficacy ~ gender_bias + age  + gender + ideology + representation_female +party_vote + se_use,
              data =  data)

main_med.out_EffFem <- mediate(med.fit_EffFem, out.fit_EffFem, treat = "gender_bias", mediator = "representation_female",
                   sims = 10000, boot = TRUE, 
                   boot.ci.type = "bca")

# nonwhite
med.fit_EffNonWhite <- lm(representation_nonwhite ~ race_bias + age  + gender + ideology + party_vote +se_use,
              data = data )
out.fit_EffNonWhite <- lm(efficacy ~ race_bias + age  + gender + ideology + representation_nonwhite +party_vote + se_use,
              data =  data)

main_med.out_EffNonWhite <- mediate(med.fit_EffNonWhite, out.fit_EffNonWhite, treat = "race_bias", mediator = "representation_nonwhite",
                   sims = 10000, boot = TRUE, 
                   boot.ci.type = "bca")

#intersectonal bias
med.fit_EffInter <- lm(representation_femaleNonwhite ~ intersectional_bias + age  + gender + ideology + party_vote +se_use,
              data = data )
out.fit_EffInter <- lm(efficacy ~ intersectional_bias + age  + gender + ideology + representation_femaleNonwhite +party_vote + se_use,
              data =  data)

main_med.out_EffInter <- mediate(med.fit_EffInter, out.fit_EffInter, treat = "intersectional_bias", mediator = "representation_femaleNonwhite",
                   sims = 10000, boot = TRUE, 
                   boot.ci.type = "bca")

## specific electability --------------------------
med.fit_SpElecFem <- lm(representation_female ~ gender_bias + age  + gender + ideology + party_vote +se_use,
              data = data )
out.fit_SpElecFem <- lm(chance_female ~ gender_bias + age  + gender + ideology + representation_female +party_vote + se_use,
              data =  data)

main_med.out_SpElecFem <- mediate(med.fit_SpElecFem, out.fit_SpElecFem, treat = "gender_bias", mediator = "representation_female",
                   sims = 10000, boot = TRUE, 
                   boot.ci.type = "bca")

# nonwhite
med.fit_SpElecNonWhite <- lm(representation_nonwhite ~ race_bias + age  + gender + ideology + party_vote +se_use,
              data = data )
out.fit_SpElectNonWhite <- lm(chance_nonwhite ~ race_bias + age  + gender + ideology + representation_nonwhite +party_vote + se_use,
              data =  data)

main_med.out_SpElecNonWhite <- mediate(med.fit_SpElecNonWhite, out.fit_SpElectNonWhite, treat = "race_bias", mediator = "representation_nonwhite",
                   sims = 10000, boot = TRUE, 
                   boot.ci.type = "bca")

#intersectional bias
med.fit_SpElecInter <- lm(representation_femaleNonwhite ~ intersectional_bias + age  + gender + ideology + party_vote +se_use,
              data = data )
out.fit_SpElecInter <- lm(chance_nonwhiteFemale ~ intersectional_bias + age  + gender + ideology + representation_femaleNonwhite +party_vote + se_use,
              data =  data)

main_med.out_SpElecInter <- mediate(med.fit_SpElecInter, out.fit_SpElecInter, treat = "intersectional_bias", mediator = "representation_femaleNonwhite",
                   sims = 10000, boot = TRUE, 
                   boot.ci.type = "bca")


# generate output tables for the appendix for the main models

# reproduce upper part Table C4.2.1
tab_model(med.fit_EffFem,
           out.fit_ElecFem, out.fit_EffFem, out.fit_SpElecFem,
          file = "outputs/Study4_TableC4.2.1_MediationGenderBias.doc")

# reproduce upper part Table C4.2.2
tab_model(med.fit_EffNonWhite,
          out.fit_ElecNonWhite, out.fit_EffNonWhite, out.fit_SpElectNonWhite,
          file = "outputs/Study4_TableC4.2.2_MediationRaceBias.doc")

# reproduce upper part Table C4.2.3
tab_model(med.fit_EffInter,
          out.fit_ElecInter, out.fit_EffInter, out.fit_SpElecInter,
          file = "outputs/Study4_TableC4.2.3_MediationIntersectionalBias.doc")


# Conduct additional mediation_analyses --------------

#In the following, we conduct all combinations of mediation models
# on different subsamples. The data is then combined into a
# single data frame which is the basis for visualization.
# 
# Note that the "mediation" library is quite vulnerable to bugs when 
# naming/referencing objects within loops/functions, which is why
# we spell out the code for each model and then summarize all 
# mediation models with a function.


###### FEMALE subsample ---------------------------------------------
#Note we remove gender as a covariate 

data_female <- data %>% filter(gender == "female")

## general electability 
med.fit <- lm(representation_female ~ gender_bias + age   + ideology + party_vote +se_use,
              data = data_female )
out.fit <- lm(viability_female ~ gender_bias + age   + ideology + representation_female +party_vote + se_use,
              data = data_female)

female_med.out_ElecFem <- mediate(med.fit, out.fit, treat = "gender_bias", mediator = "representation_female",
                                  sims = 10000, boot = TRUE, 
                                  boot.ci.type = "bca")

# nonwhite
med.fit <- lm(representation_nonwhite ~ race_bias + age   + ideology + party_vote +se_use,
              data = data_female )
out.fit <- lm(viability_nonwhite ~ race_bias + age   + ideology + representation_nonwhite +party_vote + se_use,
              data = data_female)

female_med.out_ElecNonWhite <- mediate(med.fit, out.fit, treat = "race_bias", mediator = "representation_nonwhite",
                                       sims = 10000, boot = TRUE, 
                                       boot.ci.type = "bca")

#intersectonal bias
med.fit <- lm(representation_femaleNonwhite ~ intersectional_bias + age   + ideology + party_vote +se_use,
              data = data_female )
out.fit <- lm(viability_femaleNonwhite ~ intersectional_bias + age   + ideology + representation_femaleNonwhite +party_vote + se_use,
              data = data_female)

female_med.out_ElecInter <- mediate(med.fit, out.fit, treat = "intersectional_bias", mediator = "representation_femaleNonwhite",
                                    sims = 10000, boot = TRUE, 
                                    boot.ci.type = "bca")


# external efficacy 
med.fit <- lm(representation_female ~ gender_bias + age   + ideology + party_vote +se_use,
              data = data_female )
out.fit <- lm(efficacy ~ gender_bias + age   + ideology + representation_female +party_vote + se_use,
              data = data_female)

female_med.out_EffFem <- mediate(med.fit, out.fit, treat = "gender_bias", mediator = "representation_female",
                                 sims = 10000, boot = TRUE, 
                                 boot.ci.type = "bca")

# nonwhite
med.fit <- lm(representation_nonwhite ~ race_bias + age   + ideology + party_vote +se_use,
              data = data_female )
out.fit <- lm(efficacy ~ race_bias + age   + ideology + representation_nonwhite +party_vote + se_use,
              data = data_female)

female_med.out_EffNonWhite <- mediate(med.fit, out.fit, treat = "race_bias", mediator = "representation_nonwhite",
                                      sims = 10000, boot = TRUE, 
                                      boot.ci.type = "bca")

#intersectonal bias
med.fit <- lm(representation_femaleNonwhite ~ intersectional_bias + age   + ideology + party_vote +se_use,
              data = data_female )
out.fit <- lm(efficacy ~ intersectional_bias + age   + ideology + representation_femaleNonwhite +party_vote + se_use,
              data = data_female)

female_med.out_EffInter <- mediate(med.fit, out.fit, treat = "intersectional_bias", mediator = "representation_femaleNonwhite",
                                   sims = 10000, boot = TRUE, 
                                   boot.ci.type = "bca")

## specific electability
med.fit <- lm(representation_female ~ gender_bias + age   + ideology + party_vote +se_use,
              data = data_female )
out.fit <- lm(chance_female ~ gender_bias + age   + ideology + representation_female +party_vote + se_use,
              data = data_female)

female_med.out_SpElecFem <- mediate(med.fit, out.fit, treat = "gender_bias", mediator = "representation_female",
                                    sims = 10000, boot = TRUE, 
                                    boot.ci.type = "bca")

# nonwhite
med.fit <- lm(representation_nonwhite ~ race_bias + age   + ideology + party_vote +se_use,
              data = data_female )
out.fit <- lm(chance_nonwhite ~ race_bias + age   + ideology + representation_nonwhite +party_vote + se_use,
              data = data_female)

female_med.out_SpElecNonWhite <- mediate(med.fit, out.fit, treat = "race_bias", mediator = "representation_nonwhite",
                                         sims = 10000, boot = TRUE, 
                                         boot.ci.type = "bca")

#intersectional bias
med.fit <- lm(representation_femaleNonwhite ~ intersectional_bias + age   + ideology + party_vote +se_use,
              data = data_female )
out.fit <- lm(chance_nonwhiteFemale ~ intersectional_bias + age   + ideology + representation_femaleNonwhite +party_vote + se_use,
              data = data_female)

female_med.out_SpElecInter <- mediate(med.fit, out.fit, treat = "intersectional_bias", mediator = "representation_femaleNonwhite",
                                      sims = 10000, boot = TRUE, 
                                      boot.ci.type = "bca")







###### MALE subsample ---------------------------------------------
#Note we remove gender as a covariate 

data_male <- data %>% filter(gender == "male")

## general electability 
med.fit <- lm(representation_female ~ gender_bias + age   + ideology + party_vote +se_use,
              data = data_male )
out.fit <- lm(viability_female ~ gender_bias + age   + ideology + representation_female +party_vote + se_use,
              data = data_male)

male_med.out_ElecFem <- mediate(med.fit, out.fit, treat = "gender_bias", mediator = "representation_female",
                                sims = 10000, boot = TRUE, 
                                boot.ci.type = "bca")

# nonwhite
med.fit <- lm(representation_nonwhite ~ race_bias + age   + ideology + party_vote +se_use,
              data = data_male )
out.fit <- lm(viability_nonwhite ~ race_bias + age   + ideology + representation_nonwhite +party_vote + se_use,
              data = data_male)

male_med.out_ElecNonWhite <- mediate(med.fit, out.fit, treat = "race_bias", mediator = "representation_nonwhite",
                                     sims = 10000, boot = TRUE, 
                                     boot.ci.type = "bca")

#intersectonal bias
med.fit <- lm(representation_femaleNonwhite ~ intersectional_bias + age   + ideology + party_vote +se_use,
              data = data_male )
out.fit <- lm(viability_femaleNonwhite ~ intersectional_bias + age   + ideology + representation_femaleNonwhite +party_vote + se_use,
              data = data_male)

male_med.out_ElecInter <- mediate(med.fit, out.fit, treat = "intersectional_bias", mediator = "representation_femaleNonwhite",
                                  sims = 10000, boot = TRUE, 
                                  boot.ci.type = "bca")


# external efficacy 
med.fit <- lm(representation_female ~ gender_bias + age   + ideology + party_vote +se_use,
              data = data_male )
out.fit <- lm(efficacy ~ gender_bias + age   + ideology + representation_female +party_vote + se_use,
              data = data_male)

male_med.out_EffFem <- mediate(med.fit, out.fit, treat = "gender_bias", mediator = "representation_female",
                               sims = 10000, boot = TRUE, 
                               boot.ci.type = "bca")

# nonwhite
med.fit <- lm(representation_nonwhite ~ race_bias + age   + ideology + party_vote +se_use,
              data = data_male )
out.fit <- lm(efficacy ~ race_bias + age   + ideology + representation_nonwhite +party_vote + se_use,
              data = data_male)

male_med.out_EffNonWhite <- mediate(med.fit, out.fit, treat = "race_bias", mediator = "representation_nonwhite",
                                    sims = 10000, boot = TRUE, 
                                    boot.ci.type = "bca")

#intersectonal bias
med.fit <- lm(representation_femaleNonwhite ~ intersectional_bias + age   + ideology + party_vote +se_use,
              data = data_male )
out.fit <- lm(efficacy ~ intersectional_bias + age   + ideology + representation_femaleNonwhite +party_vote + se_use,
              data = data_male)

male_med.out_EffInter <- mediate(med.fit, out.fit, treat = "intersectional_bias", mediator = "representation_femaleNonwhite",
                                 sims = 10000, boot = TRUE, 
                                 boot.ci.type = "bca")

## specific electability
med.fit <- lm(representation_female ~ gender_bias + age   + ideology + party_vote +se_use,
              data = data_male )
out.fit <- lm(chance_female ~ gender_bias + age   + ideology + representation_female +party_vote + se_use,
              data = data_male)

male_med.out_SpElecFem <- mediate(med.fit, out.fit, treat = "gender_bias", mediator = "representation_female",
                                  sims = 10000, boot = TRUE, 
                                  boot.ci.type = "bca")

# nonwhite
med.fit <- lm(representation_nonwhite ~ race_bias + age   + ideology + party_vote +se_use,
              data = data_male )
out.fit <- lm(chance_nonwhite ~ race_bias + age   + ideology + representation_nonwhite +party_vote + se_use,
              data = data_male)

male_med.out_SpElecNonWhite <- mediate(med.fit, out.fit, treat = "race_bias", mediator = "representation_nonwhite",
                                       sims = 10000, boot = TRUE, 
                                       boot.ci.type = "bca")

#intersectional bias
med.fit <- lm(representation_femaleNonwhite ~ intersectional_bias + age   + ideology + party_vote +se_use,
              data = data_male )
out.fit <- lm(chance_nonwhiteFemale ~ intersectional_bias + age   + ideology + representation_femaleNonwhite +party_vote + se_use,
              data = data_male)

male_med.out_SpElecInter <- mediate(med.fit, out.fit, treat = "intersectional_bias", mediator = "representation_femaleNonwhite",
                                    sims = 10000, boot = TRUE, 
                                    boot.ci.type = "bca")



######  DEMOCRAT subsample ---------------------------------------------
#Note we remove party_vote as a covariate 

data_democratic <- data %>% filter(party_vote == "liberal")

## general electability 
med.fit <- lm(representation_female ~ gender_bias + age   + ideology + gender +se_use,
              data = data_democratic )
out.fit <- lm(viability_female ~ gender_bias + age   + ideology + representation_female +gender + se_use,
              data = data_democratic)

democratic_med.out_ElecFem <- mediate(med.fit, out.fit, treat = "gender_bias", mediator = "representation_female",
                                      sims = 100, boot = TRUE, 
                                      boot.ci.type = "bca")

# nonwhite
med.fit <- lm(representation_nonwhite ~ race_bias + age   + ideology + gender +se_use,
              data = data_democratic )
out.fit <- lm(viability_nonwhite ~ race_bias + age   + ideology + representation_nonwhite +gender + se_use,
              data = data_democratic)

democratic_med.out_ElecNonWhite <- mediate(med.fit, out.fit, treat = "race_bias", mediator = "representation_nonwhite",
                                           sims = 10000, boot = TRUE, 
                                           boot.ci.type = "bca")

#intersectonal bias
med.fit <- lm(representation_femaleNonwhite ~ intersectional_bias + age   + ideology + gender +se_use,
              data = data_democratic )
out.fit <- lm(viability_femaleNonwhite ~ intersectional_bias + age   + ideology + representation_femaleNonwhite +gender + se_use,
              data = data_democratic)

democratic_med.out_ElecInter <- mediate(med.fit, out.fit, treat = "intersectional_bias", mediator = "representation_femaleNonwhite",
                                        sims = 10000, boot = TRUE, 
                                        boot.ci.type = "bca")


# external efficacy 
med.fit <- lm(representation_female ~ gender_bias + age   + ideology + gender +se_use,
              data = data_democratic )
out.fit <- lm(efficacy ~ gender_bias + age   + ideology + representation_female +gender + se_use,
              data = data_democratic)

democratic_med.out_EffFem <- mediate(med.fit, out.fit, treat = "gender_bias", mediator = "representation_female",
                                     sims = 10000, boot = TRUE, 
                                     boot.ci.type = "bca")

# nonwhite
med.fit <- lm(representation_nonwhite ~ race_bias + age   + ideology + gender +se_use,
              data = data_democratic )
out.fit <- lm(efficacy ~ race_bias + age   + ideology + representation_nonwhite +gender + se_use,
              data = data_democratic)

democratic_med.out_EffNonWhite <- mediate(med.fit, out.fit, treat = "race_bias", mediator = "representation_nonwhite",
                                          sims = 10000, boot = TRUE, 
                                          boot.ci.type = "bca")

#intersectonal bias
med.fit <- lm(representation_femaleNonwhite ~ intersectional_bias + age   + ideology + gender +se_use,
              data = data_democratic )
out.fit <- lm(efficacy ~ intersectional_bias + age   + ideology + representation_femaleNonwhite +gender + se_use,
              data = data_democratic)

democratic_med.out_EffInter <- mediate(med.fit, out.fit, treat = "intersectional_bias", mediator = "representation_femaleNonwhite",
                                       sims = 10000, boot = TRUE, 
                                       boot.ci.type = "bca")

## specific electability
med.fit <- lm(representation_female ~ gender_bias + age   + ideology + gender +se_use,
              data = data_democratic )
out.fit <- lm(chance_female ~ gender_bias + age   + ideology + representation_female +gender + se_use,
              data = data_democratic)

democratic_med.out_SpElecFem <- mediate(med.fit, out.fit, treat = "gender_bias", mediator = "representation_female",
                                        sims = 10000, boot = TRUE, 
                                        boot.ci.type = "bca")

# nonwhite
med.fit <- lm(representation_nonwhite ~ race_bias + age   + ideology + gender +se_use,
              data = data_democratic )
out.fit <- lm(chance_nonwhite ~ race_bias + age   + ideology + representation_nonwhite +gender + se_use,
              data = data_democratic)

democratic_med.out_SpElecNonWhite <- mediate(med.fit, out.fit, treat = "race_bias", mediator = "representation_nonwhite",
                                             sims = 10000, boot = TRUE, 
                                             boot.ci.type = "bca")

#intersectional bias
med.fit <- lm(representation_femaleNonwhite ~ intersectional_bias + age   + ideology + gender +se_use,
              data = data_democratic )
out.fit <- lm(chance_nonwhiteFemale ~ intersectional_bias + age   + ideology + representation_femaleNonwhite +gender + se_use,
              data = data_democratic)

democratic_med.out_SpElecInter <- mediate(med.fit, out.fit, treat = "intersectional_bias", mediator = "representation_femaleNonwhite",
                                          sims = 10000, boot = TRUE, 
                                          boot.ci.type = "bca")



######  REPUBLICAN subsample ---------------------------------------------
#Note we remove party_vote as a covariate 

data_republican <- data %>% filter(party_vote == "conservative" &
                                     gender != "other")

## general electability 
med.fit <- lm(representation_female ~ gender_bias + age   + ideology + gender +se_use,
              data = data_republican )
out.fit <- lm(viability_female ~ gender_bias + age   + ideology + representation_female +gender + se_use,
              data = data_republican)

republican_med.out_ElecFem <- mediate(med.fit, out.fit, treat = "gender_bias", mediator = "representation_female",
                                      sims = 10000, boot = TRUE, 
                                      boot.ci.type = "bca")

# nonwhite
med.fit <- lm(representation_nonwhite ~ race_bias + age   + ideology + gender +se_use,
              data = data_republican )
out.fit <- lm(viability_nonwhite ~ race_bias + age   + ideology + representation_nonwhite +gender + se_use,
              data = data_republican)

republican_med.out_ElecNonWhite <- mediate(med.fit, out.fit, treat = "race_bias", mediator = "representation_nonwhite",
                                           sims = 10000, boot = TRUE, 
                                           boot.ci.type = "bca")

#intersectonal bias
med.fit <- lm(representation_femaleNonwhite ~ intersectional_bias + age   + ideology + gender +se_use,
              data = data_republican )
out.fit <- lm(viability_femaleNonwhite ~ intersectional_bias + age   + ideology + representation_femaleNonwhite +gender + se_use,
              data = data_republican)

republican_med.out_ElecInter <- mediate(med.fit, out.fit, treat = "intersectional_bias", mediator = "representation_femaleNonwhite",
                                        sims = 10000, boot = TRUE, 
                                        boot.ci.type = "bca")


# external efficacy 
med.fit <- lm(representation_female ~ gender_bias + age   + ideology + gender +se_use,
              data = data_republican )
out.fit <- lm(efficacy ~ gender_bias + age   + ideology + representation_female +gender + se_use,
              data = data_republican)

republican_med.out_EffFem <- mediate(med.fit, out.fit, treat = "gender_bias", mediator = "representation_female",
                                     sims = 10000, boot = TRUE, 
                                     boot.ci.type = "bca")

# nonwhite
med.fit <- lm(representation_nonwhite ~ race_bias + age   + ideology + gender +se_use,
              data = data_republican )
out.fit <- lm(efficacy ~ race_bias + age   + ideology + representation_nonwhite +gender + se_use,
              data = data_republican)

republican_med.out_EffNonWhite <- mediate(med.fit, out.fit, treat = "race_bias", mediator = "representation_nonwhite",
                                          sims = 10000, boot = TRUE, 
                                          boot.ci.type = "bca")

#intersectonal bias
med.fit <- lm(representation_femaleNonwhite ~ intersectional_bias + age   + ideology + gender +se_use,
              data = data_republican )
out.fit <- lm(efficacy ~ intersectional_bias + age   + ideology + representation_femaleNonwhite +gender + se_use,
              data = data_republican)

republican_med.out_EffInter <- mediate(med.fit, out.fit, treat = "intersectional_bias", mediator = "representation_femaleNonwhite",
                                       sims = 10000, boot = TRUE, 
                                       boot.ci.type = "bca")

## specific electability
med.fit <- lm(representation_female ~ gender_bias + age   + ideology + gender +se_use,
              data = data_republican )
out.fit <- lm(chance_female ~ gender_bias + age   + ideology + representation_female +gender + se_use,
              data = data_republican)

republican_med.out_SpElecFem <- mediate(med.fit, out.fit, treat = "gender_bias", mediator = "representation_female",
                                        sims = 10000, boot = TRUE, 
                                        boot.ci.type = "bca")

# nonwhite
med.fit <- lm(representation_nonwhite ~ race_bias + age   + ideology + gender +se_use,
              data = data_republican )
out.fit <- lm(chance_nonwhite ~ race_bias + age   + ideology + representation_nonwhite +gender + se_use,
              data = data_republican)

republican_med.out_SpElecNonWhite <- mediate(med.fit, out.fit, treat = "race_bias", mediator = "representation_nonwhite",
                                             sims = 10000, boot = TRUE, 
                                             boot.ci.type = "bca")

#intersectional bias
med.fit <- lm(representation_femaleNonwhite ~ intersectional_bias + age   + ideology + gender +se_use,
              data = data_republican )
out.fit <- lm(chance_nonwhiteFemale ~ intersectional_bias + age   + ideology + representation_femaleNonwhite +gender + se_use,
              data = data_republican)

republican_med.out_SpElecInter <- mediate(med.fit, out.fit, treat = "intersectional_bias", mediator = "representation_femaleNonwhite",
                                          sims = 10000, boot = TRUE, 
                                          boot.ci.type = "bca")



# Save an image of the data for future use so the models don't
# have to be re-run every time.
# Note that the main models from the section H4 should also have been run at this point

save.image(file = "outputs/Study4_AllMediationModels.RData")






# Visualization: Figure 6 ------------------------------------
# There are two ways to get the data for Figure 6.
# 1. Run all the mediation models in this script. This takes a while 
# 2. Load the saved R image from the outputs.


# Either way, we first need to extract the results from the mediation models
# with the following function/loop

##### Gather results of mediation analyses ---------------
# Initialize an empty list to store the results
results_list <- list()

# Loop through all objects in the R environment
for (obj_name in ls()) {
  # Check if the object name contains "_med.out_"
  if (grepl("_med.out_", obj_name)) {
    # Get the mediation object by name using get()
    med_out <- get(obj_name)
    
    # Extract the necessary information
    acme <- med_out$d.avg
    ci.lower <- med_out$d.avg.ci[1]
    ci.upper <- med_out$d.avg.ci[2]
    
    # Store the information in a list
    results_list[[length(results_list) + 1]] <- data.frame(
      model_name = obj_name,
      acme = acme,
      ci.lower = ci.lower,
      ci.upper = ci.upper,
      stringsAsFactors = FALSE
    )
  }
}

# Combine all the data frames in the results_list into one data frame
results_df <- do.call(rbind, results_list)



# do some data manipulation to get clean variables for visualization
med_data <- results_df %>%
  separate(
    model_name, 
    into = c("sample", "trash", "descriptor"), # Names for the new variables
    sep = "_",  # Separator (underscore)
    extra = "merge",  # To handle cases where there might be more than 3 parts
    fill = "right")%>%  # Fill with NA if there are fewer than 3 parts
  mutate(
    condition = case_when(
      grepl("Fem", descriptor) ~ "Gender bias",
      grepl("NonWhite", descriptor) ~ "Race bias",
      grepl("Inter", descriptor) ~ "Double bias",
      TRUE ~ NA_character_  # Fallback in case none of the conditions are met
    ),
    outcome = case_when(
      grepl("Eff", descriptor) ~ "External efficacy",
      grepl("SpElec", descriptor) ~ "Specific electability",
      grepl("Elec", descriptor) & !grepl("SpElec", descriptor) ~ "General electability",
      TRUE ~ NA_character_  # Fallback in case none of the conditions are met
    ),
    is_full_sample = case_when(
      sample == "main" ~ "yes",
      sample != "main" ~ "no"
    ),
    sample = fct_recode(sample,
                        "Full" = "main",
                        "Male respondents" = "male",
                        "Female respondents" = "female",
                        "Republicans" = "republican",
                        "Democrats" = "democratic"),
    sample = fct_relevel(sample,
                         "Democrats", "Republicans",
                         "Female respondents","Male respondents",
                         "Full"),
    condition = fct_relevel(condition,
                            "Gender bias","Race bias","Double bias"),
    outcome = fct_relevel(outcome, 
                          "General electability","Specific electability","External efficacy"),
    acme = round(acme, 3))





Figure6 <- med_data %>%
  ggplot(aes(
    y = sample, x = acme, xmin = ci.lower, xmax = ci.upper,
    col = is_full_sample)) +
  geom_vline(xintercept = 0, linetype = "dashed")+
  geom_pointrange()+
  geom_text(data = filter(med_data, is_full_sample == "yes"),
            aes(label = acme),  size = 2.5,
            vjust = -0.73, color = "black")+  
  facet_grid(condition ~ outcome, switch = "y") +
  theme_classic() +
  coord_flex_cart(left = capped_vertical("both")) +
  scale_color_manual(
    values = c("grey60","#3b528b"))+
  labs(y = "", x = "",
       title = "")+
  theme(
    legend.position = "bottom",
    strip.text.x = element_text(
      size = 12, face = "bold"),
    strip.text.y = element_text(
      face = "bold"),
    strip.background = element_blank())+
  # theme(panel.spacing = unit(2, "lines")) +
  guides(color = "none")


ggsave(Figure6, filename = "outputs/Study4_Figure6.jpeg", dpi = 800,
       width = 7, height = 6)
